package nc.impl.ic.ws;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.RuntimeEnv;
import nc.itf.ic.ws.IVmiSerivceWS;
import nc.itf.single.pub.ExceptionUtil;
import nc.itf.single.pub.LogUtil;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.ResultSetProcessor;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.log.LogVO;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class VmiSerivceWSImpl implements IVmiSerivceWS {

	private BaseDAO baseDao = null;

	public String scmQueryBySupplier(String supplierCode, String startDate,
			String endDate) throws BusinessException {
		InvocationInfoProxy.getInstance().setUserDataSource("jmcgnc");
		LogVO mes = new LogVO();
		mes.setFuncode("vmiQueryBySupplier");
		mes.setFunname("VMI供应商进销存收发报表");
		mes.setCparam("【供应商："+supplierCode+"】【startDate："+startDate+"】【endDate："+endDate+"】");
		mes.setDef1(supplierCode);
		mes.setDef2(startDate);
		mes.setDef3(endDate);
		mes.setSendtime(new UFDateTime(new Date()));
		
		String cresult = null;
		List<Map<String, Object>> data = null;
		try{
			Map<String, String> condition = initParam(supplierCode, startDate,
					endDate);

			data = query(condition);

			if (data == null || data.size() == 0)
				throw new BusinessException("数据查询返回0，建议修改查询条件");
			
			mes.setDef4("成功");
			cresult = createResult(data);
			
		}catch(Exception e){
			LogUtil.appendMessage(mes, ExceptionUtil.getStackTrace(e));
			mes.setDef4("失败");
			cresult = createErrResult(e);
		}
		
		mes.setCresult(cresult);
		mes.setRecptime(new UFDateTime(new Date()));
		LogUtil.insert(mes);

		return cresult;
	}

	private String createErrResult(Exception err) {
		String xml = null;

		try {
			Document doc = DocumentHelper.parseText("<root/>");
			Element root = doc.getRootElement();
			Element error = root.addElement("error");
			error.addElement("message").setText(err.getMessage());
			xml = outPutXml(doc);

		} catch (DocumentException e) {
			e.printStackTrace();
		}

		return xml;
	}

	private String createResult(List<Map<String, Object>> data) {

		String xml = null;

		try {
			Document doc = DocumentHelper.parseText("<root/>");
			Element root = doc.getRootElement();

			String key = null;
			Object value = null;
			for (Map<String, Object> map : data) {
				Element item = root.addElement("item");

				for (Iterator<String> iter = map.keySet().iterator(); iter
						.hasNext();) {
					key = iter.next();
					value = map.get(key);
					value = value == null ? "" : value.toString();
					item.addElement(key).setText((String) value);
				}
			}

			xml = outPutXml(doc);

		} catch (DocumentException e) {
			e.printStackTrace();
		}

		return xml;
	}

	@SuppressWarnings("unchecked")
	private List<Map<String, Object>> query(Map<String, String> condition) throws BusinessException {
		 String sql = readFileContent("vmiQuery.sql");
		 if(sql.length() == 0) throw new BusinessException("未正确配置查询脚本'home/resources/ic/script/vmiQuery.sql'");
		 String key = null;
		 String value = null;
		 for(Iterator<String> iter = condition.keySet().iterator(); iter.hasNext();){
			 key = iter.next();
			 value = condition.get(key);
			 sql = sql.replaceAll("#"+key+"#", "'"+value+"'");
		 }
		 
		 List<Map<String, Object>> data = (List<Map<String, Object>>) getBaseDao().executeQuery(sql, new ResultSetProcessor() {
			
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			public List<Map<String, Object>> handleResultSet(ResultSet rs) throws SQLException {
				ResultSetMetaData metaData = rs.getMetaData();
				int cols = metaData.getColumnCount();
				
				List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
				
				while (rs.next()) {
					Map<String, Object> map = new HashMap<String, Object>();
					for (int i = 1; i <= cols; i++) {
						Object value = rs.getObject(i) == null ? "" : "" + rs.getObject(i);
						String propName = metaData.getColumnLabel(i);
						if (propName == null) {
							propName = metaData.getColumnName(i);
						}
						map.put(propName, value);
					}
					result.add(map);
				}
				
				return result;
			}
		});

		return data;
	}

	public String readFileContent(String fileName) {
		String nchome = RuntimeEnv.getInstance().getNCHome();
		String sqlPath = nchome + "/resources/ic/script/" + fileName;

		File file = new File(sqlPath);
		BufferedReader reader = null;
		StringBuffer sbf = new StringBuffer();
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempStr;
			while ((tempStr = reader.readLine()) != null) {
				sbf.append(tempStr);
			}
			reader.close();
			return sbf.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return sbf.toString();
	}

	private Map<String, String> initParam(String supplierCode,
			String startDate, String endDate) throws BusinessException {

		check(supplierCode, startDate, endDate);
		
		String supplierID = (String) getBaseDao().executeQuery("select pk_cumandoc from bd_cumandoc where dr=0 and pk_corp='1021' and (custflag = '1' or custflag = '3') and pk_cubasdoc in (select bd_cubasdoc.pk_cubasdoc from bd_cubasdoc where dr=0 and custcode = '"+supplierCode+"')", new ColumnProcessor());
		
		if(supplierID == null || supplierID.length() == 0) throw new BusinessException("供应商【"+supplierCode+"】,在NC中不存在或者未分配晶码公司");
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		//获取开始日期的上个月的相关时间
		Date date1 = null;
		Date date2 = null;
		
		try {
			date1 = sdf.parse(startDate);
		} catch (ParseException e) {
			throw new BusinessException("参数【startDate='"+startDate+"'】格式不正确yyyy-MM-dd，请修改");
		}
		
		Calendar cdate1 = Calendar.getInstance();
		cdate1.setTime(date1);
		cdate1.set(Calendar.MONTH, cdate1.get(Calendar.MONTH) - 1);
		String dbizMonth = sdf.format(cdate1.getTime()).substring(0, 7);
		String dbizDate = dbizMonth + "-01";
		
		try {
			date2 = sdf.parse(endDate);
		} catch (ParseException e) {
			throw new BusinessException("参数【endDate='"+startDate+"'】格式不正确yyyy-MM-dd，请修改");
		}
		
		Calendar cdate2 = Calendar.getInstance();
		cdate2.setTime(date1);
		cdate2.set(Calendar.DATE, cdate2.get(Calendar.DATE) - 1);
		endDate = sdf.format(cdate2.getTime());
		
		Map<String, String> condition = new HashMap<String, String>();
		condition.put("supplierID", supplierID);
		condition.put("startDate", startDate);
		condition.put("endDate", endDate);
		condition.put("dbizMonth", dbizMonth);
		condition.put("dbizDate", dbizDate);

		return condition;
	}

	private void check(String supplierCode, String startDate, String endDate) throws BusinessException {

		if(supplierCode == null || supplierCode.length() == 0) throw new BusinessException("参数【supplierCode】不允许为空");
		if(startDate == null || startDate.length() == 0) throw new BusinessException("参数【startDate】不允许为空");
		if(endDate == null || endDate.length() == 0) throw new BusinessException("参数【endDate】不允许为空");
		
		Date date1 = null;
		Date date2 = null;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			date1 = sdf.parse(startDate);
		} catch (ParseException e) {
			throw new BusinessException("参数【startDate='"+startDate+"'】格式不正确yyyy-MM-dd，请修改");
		}
		
		try {
			date2 = sdf.parse(endDate);
		} catch (ParseException e) {
			throw new BusinessException("参数【endDate='"+startDate+"'】格式不正确yyyy-MM-dd，请修改");
		}
		
		if(date1.after(date2)){
			throw new BusinessException("参数【结束日期】不能小于【开始日期】，请修改");
		}
	}
	
	private String outPutXml(Document doc) {
		OutputFormat oFormat = OutputFormat.createPrettyPrint(); 
		oFormat.setEncoding("UTF-8");
        StringWriter sWriter = new StringWriter(); 
        XMLWriter xWriter = new XMLWriter(sWriter, oFormat);
        try { 
            xWriter.write(doc); //为document
            xWriter.flush(); 
            xWriter.close(); 
	    } catch (IOException e) { 
	    } 
        return sWriter.toString();
	}

	public BaseDAO getBaseDao() {
		if(baseDao == null){
			baseDao = new BaseDAO("jmcgnc");
		}
		
		return baseDao;
	}
}
